#ifndef __GlDxGraphicComponent_h__
#define __GlDxGraphicComponent_h__

#include <d3d11.h>
#include "GlGraphicComponent.h"
#include "GlPosition.h"

namespace GraphicLibrary
{
	class Matrix4x4;

	class DxGraphicComponent
		: public virtual GraphicComponent
	{
		public:
			enum ExceptionList
			{
				ElUnableToCreateBuffers
			};

			DxGraphicComponent();
			virtual ~DxGraphicComponent();
			virtual void move(const Position &newPos);
			virtual float getX() const;
			virtual float getY() const;
			virtual void setDirection(float rotation);
			virtual void setVisibility(const bool visible);
			virtual bool isVisible() const;
			virtual void setLayer(const float layer);
			virtual float getLayer() const;
			virtual void tick(const float deltaTime);
			virtual Matrix4x4 getTransformationMatrix() const = 0;
			virtual void apply(ID3D11DeviceContext *ic) const = 0;

			inline float getRotateAngle() const	{return mRotation;}
			template<typename Type>
				Type* cast()
				{
					if(mTypeInfo == &typeid(Type))
						return reinterpret_cast<Type*>(mSelfPointer);
					return 0;
				}
			template<typename Type>
				const Type* cast() const
				{
					return const_cast<DxGraphicComponent*>(this)->cast<Type>();
				}
		protected:
			struct VertexData
			{
				float	mPos[2];
				float	mUV[2];
			};
			typedef unsigned int IndexData;
			template<typename Type>
				void setSelf(Type *self)
				{
					mTypeInfo = &typeid(Type);
					mSelfPointer = self;
				}

			ID3D11Buffer* createVertexBuffer(ID3D11Device *device, const UINT size, const void *data) const;
			ID3D11Buffer* createIndexBuffer(ID3D11Device *device, const UINT size, const void *data) const;
		private:
			Position	mPos;
			bool		mVisibility;
			float		mLayer;
			float		mRotation;

			const type_info*	mTypeInfo;
			void*				mSelfPointer;
	};
}

#endif // __GlDxGraphicComponent_h__
